#include "p_tengine.h"

#include "p_error.h"

p_template_engine_struct template_engine_struct_create()
{
   // TODO: Implement it!
   p_template_engine_struct result;
   result.token_list = 0;
   return result;
}

p_template_engine_struct template_engine_struct_create(
                                                       const p_template_engine_struct &template_engine_struct)
{
   // TODO: Implement it!
   p_template_engine_struct result;
   result.token_list = template_engine_struct.token_list;
   return result;
}

void template_engine_struct_init(
                                 p_template_engine_struct_ptr template_engine_struct)
{
   // TODO: Implement it!
   template_engine_struct->token_list = 0;
   template_engine_struct->index = 0;

}

// -----------------------------------------------------------------------------

bool test_token(p_template_engine_struct_ptr template_engine_struct,
                const p_unsigned_int &index, const p_token_type &tok_type)
{
   //   if (template_engine_struct->token_list &&)
   return template_engine_struct->token_list && (template_engine_struct->index
            < template_engine_struct->token_list->size()) && (
            template_engine_struct->token_list->at(index).type == tok_type);
}

std::string template_engine_create_instance(p_template_engine_struct_ptr info)
{
   return "";
}

void parse_template_parameter(p_template_engine_struct_ptr info)
{
   if (!test_token(info, info->index, TOK_RBRC)) {
   }
}

void parse_template_parameters(p_template_engine_struct_ptr info)
{
   if (!test_token(info, info->index, TOK_RBRO)) {
      throw error_struct_create("'(' expected for parameter definitions!");
   }

   // parsing a template parameter definition...
   do {
      ++(info->index);
      parse_template_parameter(info);
   } while (test_token(info, info->index, TOK_COLON));

   if (!test_token(info, info->index, TOK_RBRC)) {
      throw error_struct_create("')' expected for parameter definition!");
   }
   ++(info->index);
}

void parse_template_definition(p_template_engine_struct_ptr info)
{
   if (!test_token(info, info->index, TOK_IDENT)) {
      throw error_struct_create("Template-identifier expected!");
   }
   std::string name = info->token_list->at(info->index).ident;
   ++(info->index);

   // now we have to parse the template parameters...
   parse_template_parameters(info);
}

void template_engine_create_template(p_template_engine_struct_ptr info)
{
   parse_template_definition(info);
}

// -----------------------------------------------------------------------------

std::string template_engine_run(
                                p_template_engine_struct_ptr template_engine_struct,
                                p_token_struct_list_ptr token_list,
                                const p_unsigned_int &index)
{
   // setting the template engine elements...
   template_engine_struct->token_list = token_list;
   template_engine_struct->index = index;
   // end.

   // well the first test has to be the check whether the first token is a TOK_TEMPLATE instance...
   if (!test_token(template_engine_struct, template_engine_struct->index,
                   TOK_TEMPLATE)) {
      throw error_struct_create("A template token must be the first one!");
   }
   ++(template_engine_struct->index);

   // well the first test is whether it is a template instance or a template definition...
   if (test_token(template_engine_struct, template_engine_struct->index,
                  TOK_RBRO)) {
      // well now we have template instance
      return template_engine_create_instance(template_engine_struct);
   } else {
      // now we have template definition
      template_engine_create_template(template_engine_struct);
   }

   return "";
}
